﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
using Lynn.Infastructure.Utils;

namespace Lynn.Infastructure.AutoTask
{
    public class TaskConfig
    {
        IServiceCollection _services;
        internal ConcurrentDictionary<string, TaskOptions> Configs = new ConcurrentDictionary<string, TaskOptions>();
        public TaskConfig(IServiceCollection services, IConfiguration config) {
            _services = services;
            SetConfigs(config);
            FindAutoTasks();
        }
        void FindAutoTasks()
        {
            var tasks = AssemblyHelper.FindTypeInfos(x => x.IsClass && x.BaseType == typeof(TaskBackgroundService) && Configs.Keys.Contains(x.Name));
            tasks.ForEach(x => {
                MethodInfo mi = this.GetType().GetMethod("Task").MakeGenericMethod(new Type[] { x.AsType() });
                mi.Invoke(this, null);
            });
        }
        void SetConfigs(IConfiguration config) {
            var list = new List<TaskOptions>();
            config.Bind(list);
            foreach (var item in list) {
                Configs.TryAdd(item.Name, item);
            }
        }
        public void Task<T>() where T : TaskBackgroundService
        {
            _services.AddSingleton<T>();
            _services.AddHostedService(x=> {
                var type = x.GetService<T>();
                type.Option = Configs[typeof(T).Name];
                type.Services = x;
                return type;
            });
        }
    }
}
